import { constants } from "@/utils/constants";
import { ApiResponse } from "./types";
import axios from "axios";
import CryptoJS from "crypto-js"; //加密库
import { reject } from "lodash-es";
import { resolve } from "path";

//获取时间戳
function getISO8601Time() {
  return new Date().toISOString().replace(/\.\d+Z$/, "Z");
}
function canonicalizedQuery(queryParamsMap: any) {
  const sortedParams = Object.keys(queryParamsMap).sort();
  const encodedParams = sortedParams.map((key) => {
    const value = queryParamsMap[key];
    return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
  });
  return encodedParams.join("&");
}
//生成唯一随机数uuid
function getUniqueNonce() {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    const r = (Math.random() * 16) | 0;
    const v = c === "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}
/***
 * 构造签名字符串
 * @param method       HTTP请求的方法
 * @param urlPath      HTTP请求的资源路径
 * @param queryString  规范化的请求字符串
 * @return 签名字符串
 */
function createStringToSign(
  method: string,
  urlPath: string,
  queryString: string
) {
  return `${method}&${encodeURIComponent(urlPath)}&${encodeURIComponent(
    queryString
  )}`;
}
/***
 * 计算签名
 * @param stringToSign      签名字符串
 * @param accessKeySecret   阿里云AccessKey Secret加上与号&
 * @return 计算得到的签名
 */
function sign(stringToSign: string, accessKeySecret: string) {
  const signature = CryptoJS.HmacSHA1(stringToSign, accessKeySecret).toString(
    CryptoJS.enc.Base64
  );
  console.log("计算得到的签名：", signature);
  const signUrlEncode = encodeURIComponent(signature);
  console.log("UrlEncode编码后的签名：", signUrlEncode);
  return signUrlEncode;
}
function processGETRequest(queryString: string): Promise<ApiResponse> {
  const url = constants.API_ALIYUN_GET_TOKEN;
  const fullUrl = url + "?" + queryString;
  return new Promise((resolve, reject) => {
    axios({
      url: fullUrl,
      method: "get",
      headers: {
        Accept: "application/json; charset=UTF-8",
      },
    })
      .then((res) => {
        resolve(res);
      })
      .catch((err) => reject(err));
  });
}
/**
 * 获取阿里云token
 * @return
 */
function aliyunApiGetToken() {
  return new Promise(async (resolve, reject) => {
    const accessKeyId = constants.ACCESSKEYID_ALIYUN;
    const accessKeySecret = constants.SECRET_ALIYUN;
    const queryParamsMap = {
      AccessKeyId: constants.ACCESSKEYID_ALIYUN,
      Action: "CreateToken",
      Version: "2019-02-28",
      Timestamp: getISO8601Time(),
      Format: "JSON",
      RegionId: "cn-shanghai",
      SignatureMethod: "HMAC-SHA1",
      SignatureVersion: "1.0",
      SignatureNonce: getUniqueNonce(),
    };
    const queryString = canonicalizedQuery(queryParamsMap);
    if (!queryString) {
      console.error("Failed to construct canonicalized query string.");
      reject("Failed to construct canonicalized query string.");
      return;
    }
    const method = "GET";
    const urlPath = "/";
    const stringToSign = createStringToSign(method, urlPath, queryString);
    if (!stringToSign) {
      console.error("Failed to construct string to sign.");
      reject("Failed to construct string to sign.");
      return;
    }
    /**
     * 3.计算签名
     */
    const signature = sign(stringToSign, accessKeySecret + "&");
    if (!signature) {
      console.error("Failed to calculate signature.");
      reject("Failed to calculate signature.");
      return;
    }
    const queryStringWithSign = `Signature=${signature}&${queryString}`;
    console.log("带有签名的请求字符串：", queryStringWithSign);
    try {
      const response = await processGETRequest(queryStringWithSign);
      console.log("请求token的响应：", response, response.status === 200);
      const result = response.data;
      if (response.status === 200) {
        console.log("请求token成功 data:", result);
        try {
          const tokenObj = result.Token;
          console.log("tokenObj:", tokenObj);
          if (tokenObj) {
            const token = tokenObj.Id;
            const expireTime = tokenObj.ExpireTime;
            console.log(
              "获取的Token：",
              token,
              "有效期时间戳（秒）：",
              expireTime
            );
            const expireDate = new Date(expireTime * 1000).toLocaleString(
              "zh-CN",
              {
                timeZone: "Asia/Shanghai",
              }
            );
            console.log("Token有效期的北京时间：", expireDate);

            // 其他处理逻辑...

            resolve(tokenObj); // 返回获取的Token
          } else {
            console.error("返回的响应结果中缺少Token字段");
            reject("返回的响应结果中缺少Token字段");
          }
        } catch (error) {
          console.error("解析JSON时发生错误：", error);
          reject("解析JSON时发生错误：" + error);
        }
      } else {
        console.error("提交获取Token请求失败：", result);
        reject("提交获取Token请求失败：" + result);
      }
    } catch (error) {
      console.error("请求失败：", error);
      reject("请求失败：" + error);
    }
  });
}
export { aliyunApiGetToken };
